package evemanutool.utils.calc; import java.util.ArrayList; import java.util.Date; import evemanutool.constants.DBConstants; import evemanutool.constants.UserPrefConstants; import evemanutool.data.cache.MarketInfoEntry; import evemanutool.data.cache.TradeEntry; import evemanutool.data.cache.TradeHistoryEntry; import evemanutool.data.database.Item; import evemanutool.prefs.Preferences; import evemanutool.prefs.Preferences.MarketAction; import evemanutool.prefs.Preferences.MarketPriceType; import evemanutool.prefs.Preferences.MarketTax; import evemanutool.utils.databases.PriceDB; public class MarketCalculator implements UserPrefConstants, DBConstants { public static double calculatePrice(Action a, int typeId, PriceDB pdb, Preferences prefs) { //Returns the cost/income of acquiring/selling an item including taxes. double val = 0; MarketInfoEntry mI = null; if (a == Action.BUY) { //Buy Action. //Set MarketInfo and return 0 if not valid. mI = pdb.getBuyMI(typeId); if (mI == null) { return val; } val = mI.getPrice(MARKET_AIM_ENUM[prefs.getMarketOrderAimIndex(MarketAction.BUY_ACTION)]) .getValue(MARKET_PRICE_ENUM[prefs.getMarketPriceTypeIndex(MarketPriceType.BUY_TYPE)]); //Add broker. val += val * prefs.getMarketTax(MarketTax.BROKER_FEE) / 100; }else if (a == Action.SELL){ //Sell Action. //Set MarketInfo and return 0 if not valid. mI = pdb.getSellMI(typeId); if (mI == null) { return val; } val = mI.getPrice(MARKET_AIM_ENUM[prefs.getMarketOrderAimIndex(MarketAction.SELL_ACTION)]) .getValue(MARKET_PRICE_ENUM[prefs.getMarketPriceTypeIndex(MarketPriceType.SELL_TYPE)]); //Add sales and broker. val -= val * (prefs.getMarketTax(MarketTax.SALES_TAX) + prefs.getMarketTax(MarketTax.BROKER_FEE)) / 100; } return val; } public static boolean isItemAvailable(Item i, PriceDB pdb, Preferences prefs) { //Determine if BPO is seeded. if(i.isOnMarket()) { ArrayList<TradeEntry> tEL = pdb.getBuyTH(i.getTypeId()).getHistory(); TradeEntry tE; return (!tEL.isEmpty() && (tE = tEL.get(0)) != null && (tE.getVolume() > 0 || tE.getOrders() > 0) && MarketCalculator.calculatePrice(Action.BUY, i.getTypeId(), pdb, prefs) > 0); } return false; } public static Trend calculateMarketTrend(Action a, Item i, PriceDB pdb, Preferences prefs) { //Determine the general market trend. TradeHistoryEntry tHE ; if (a == Action.SELL) { tHE = pdb.getSellTH(i.getTypeId()); } else { tHE = pdb.getBuyTH(i.getTypeId()); } if(i.isOnMarket() && tHE.getHistory().size() > MINIMUM_HISTORY_SIZE) { //5 day average. double avg5 = calculateTimedMarketAverage(tHE, 5); //10 day average. double avg10 = calculateTimedMarketAverage(tHE, 10); //15 day average. double avg15 = calculateTimedMarketAverage(tHE, 15); //Full average, (PriceDB.HISTORY_MAX_DAYS). double avgFull = calculateTimedMarketAverage(tHE, -1); //Check for holes in the data. if (avg5 == 0 || avg10 == 0 || avg15 == 0 || avgFull == 0) { return Trend.INCONCLUSIVE; } if ((avg15 / avgFull) - 1 > SIGNIFICANT_DIFF) { //Rising average. if ((avg5 / avg15) - 1 > SIGNIFICANT_DIFF) { //Rising average. return Trend.RISING; } else if ((avg5 / avg15) - 1 < -SIGNIFICANT_DIFF) { //Falling average. return Trend.UNSTABLE; }else { //Stable average. return Trend.RISING; } } else if ((avg15 / avgFull) - 1 < -SIGNIFICANT_DIFF) { //Falling average. if ((avg5 / avg15) - 1 > SIGNIFICANT_DIFF) { //Rising average. return Trend.UNSTABLE; } else if ((avg5 / avg15) - 1 < -SIGNIFICANT_DIFF) { //Falling average. return Trend.FALLING; }else { //Stable average. return Trend.FALLING; } }else { //Stable average. if ((avg5 / avg15) - 1 > SIGNIFICANT_DIFF) { //Rising average. return Trend.UNSTABLE; } else if ((avg5 / avg15) - 1 < -SIGNIFICANT_DIFF) { //Falling average. return Trend.UNSTABLE; }else { //Stable average. return Trend.STABLE; } } } return Trend.INCONCLUSIVE; } private static double calculateTimedMarketAverage(TradeHistoryEntry tHE, int days) { //Calculate the price average of the latest x days or entire history if days == -1. double ans = 0; int counter = 0; Date earliestAccepted = new Date(System.currentTimeMillis() - (days * 24 * 3600 * 1000)); for (TradeEntry pHE : tHE.getHistory()) { if (pHE.getDate().after(earliestAccepted) || days == -1) { ans += pHE.getAvgPrice(); counter++; } else { break; } } ans /= (double) counter; return ans; } }